package com.kongjian.manage.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kongjian.manage.mapper.DeptMapper;
import com.kongjian.manage.mapper.UserDeptMapper;
import com.kongjian.manage.mapper.UserMapper;
import com.kongjian.manage.model.entity.DeptEntity;
import com.kongjian.manage.model.entity.UserDeptEntity;
import com.kongjian.manage.model.entity.UserEntity;
import com.kongjian.manage.model.vo.UserInfoVo;
import com.kongjian.manage.service.OauthUserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.List;
import java.util.Map;

@Service
public class OauthUserServiceImpl implements OauthUserService {

    @Resource
    RestTemplate restTemplate;

    @Value("${cas.integrate.oauth20.client-id}")
    private String clientId;

    @Value("${cas.integrate.oauth20.client-secret}")
    private String clientSecret;

    @Value("${cas.integrate.oauth20.redirect-url}")
    private String redirectUrl;

    @Value("${cas.integrate.oauth20.server-address}")
    private String serverAddress;

    @Override
    public String getAccessToken(String code) {
        String url = serverAddress + "/accessToken?grant_type=authorization_code&client_id=%s&client_secret=%s&redirect_uri=%s&code=%s";

        String realUrl = String.format(url, clientId, clientSecret, redirectUrl, code);

        //示例:access_token=AT-564-UPz0VDE0XwA1B7s0VGuCjHi0IZdhNKds&scope=&expires_in=28800&token_type=bearer&
        String result = restTemplate.getForObject(realUrl, String.class);
        String accessToken = result.split("&")[0].split("=")[1].toString();

        return accessToken;
    }

    @Override
    public UserInfoVo getUserInfo(String accessToken) {
        //1.通过accessToken获取用户信息
        String url = serverAddress + "/profile?access_token=" + accessToken;
        ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
        String body = result.getBody();
        Map<String, Object> map = JSONObject.parseObject(body, new TypeReference<Map<String, Object>>() {
        });
        // 这个attributes的数据格式怎么是这样的？每个属性表示一个对象
        String attributes = map.get("attributes").toString();
        attributes = attributes.replaceFirst("\\[", "").replace("]", "").replaceAll("\\},\\{", ",");
        UserInfoVo userVo = JSONObject.parseObject(attributes, UserInfoVo.class);

        //2.解析attributes的方法是，先进行base64解码，再用UTF-8编码
        Class<?> clazz = userVo.getClass();
        // 获取对象的所有属性
        Field[] fields = clazz.getDeclaredFields();
        // 遍历属性数组
        for (Field field : fields) {
            field.setAccessible(true);
            Object fieldValue = null;
            String fileName = null;
            try {
                fieldValue = field.get(userVo);
                fileName = field.getName();
                if (fieldValue != null){
                    byte[] decodedBytes = Base64.getDecoder().decode(fieldValue + "");
                    fieldValue = new String(decodedBytes, StandardCharsets.UTF_8);
                }
                field.setAccessible(true);
                field.set(userVo, fieldValue);
                System.out.println(fileName + ":" + fieldValue);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }

        return userVo;
    }

    @Resource
    private UserMapper userMapper;

    @Resource
    private DeptMapper deptMapper;

    @Resource
    private UserDeptMapper userDeptMapper;

    @Override
    public UserInfoVo getUser(String code) {
        String accessToken = getAccessToken(code);
        UserInfoVo userInfo = getUserInfo(accessToken);

        LambdaQueryWrapper<DeptEntity> deptEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        deptEntityLambdaQueryWrapper.eq(DeptEntity::getFDeptId,userInfo.getF_dept_id());
        List<DeptEntity> deptEntities = deptMapper.selectList(deptEntityLambdaQueryWrapper);
        if (deptEntities.isEmpty()){
            //部门信息
            DeptEntity deptEntity = new DeptEntity();
            deptEntity.setFDeptId(userInfo.getF_dept_id());
            deptEntity.setFDeptDwcode(userInfo.getF_dept_dwcode());
            deptEntity.setFDeptCode(userInfo.getF_dept_code());
            deptEntity.setFDeptDwname(userInfo.getF_dept_dwname());
            deptEntity.setFDeptFullname(userInfo.getF_dept_fullname());
            deptEntity.setFDeptName(userInfo.getF_dept_name());
            deptEntity.setCreateUser(-1l);
            deptEntity.setCreateTime(LocalDateTime.now());
            deptMapper.insert(deptEntity);
        }

        //用户信息
        LambdaQueryWrapper<UserEntity> userEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userEntityLambdaQueryWrapper.eq(UserEntity::getFUserId,userInfo.getF_user_id());
        List<UserEntity> userEntities = userMapper.selectList(userEntityLambdaQueryWrapper);
        if(userEntities.isEmpty()) {
            UserEntity userEntity = new UserEntity();
            userEntity.setFUserId(userInfo.getF_user_id());
            userEntity.setFUserCountry(userInfo.getF_user_country());
            userEntity.setFUserCode(userInfo.getF_user_code());
            userEntity.setFUserGuid(userInfo.getF_user_guid());
            userEntity.setFUserName(userInfo.getF_user_name());
            userEntity.setFUserSex(userInfo.getF_user_sex());
            userEntity.setFUserUnit(userInfo.getF_user_unit());
            userEntity.setFUserFirstName(userInfo.getF_user_first_name());
            userEntity.setFUserLastName(userInfo.getF_user_last_name());
            userEntity.setCreateUser(-1l);
            userEntity.setCreateTime(LocalDateTime.now());
            userMapper.insert(userEntity);
            //部门员工关系表
            UserDeptEntity userDeptEntity = new UserDeptEntity();
            userDeptEntity.setDeptId(userInfo.getF_dept_id());
            userDeptEntity.setUserId(userInfo.getF_user_id());
            userDeptMapper.insert(userDeptEntity);
        }
        return userInfo;
    }


}
